package com.mz.mattress.admin.service.impl;

import com.mz.mattress.admin.config.LoginProperties;
import com.mz.mattress.admin.config.RsaProperties;
import com.mz.mattress.admin.entity.SysUser;
import com.mz.mattress.admin.mapper.*;
import com.mz.mattress.admin.service.AuthService;
import com.mz.mattress.api.redis.RedisKeys;
import com.mz.mattress.api.common.Result;
import com.mz.mattress.api.enums.*;
import com.mz.mattress.api.jwt.JwtTokenUtil;
import com.mz.mattress.api.jwt.AdminJwt;
import com.mz.mattress.api.req.LoginReq;
import com.mz.mattress.api.util.*;
import com.wf.captcha.base.Captcha;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class AuthServiceImpl implements AuthService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private LoginProperties loginProperties;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private CodeValidateUtil codeValidateUtil;

    @Override
    public Result loginBiz(LoginReq loginReq) {

        Result result = codeValidateUtil.validateImgCode(loginReq.getUuid(), loginReq.getCode());
        if (result.isFail()) {
            return result;
        }

        // 密码解密
        String password = null;
        try {
            password = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey, loginReq.getPassword());
        } catch (Exception e) {
            return Result.fail("密码解密报错");
        }

        String username = loginReq.getUsername();

        List<SysUser> sysUsers = sysUserMapper.selectByUsername(username);
        if (sysUsers.size() == 0) {
            return Result.fail("未找到用户");
        }
        if (sysUsers.size() > 1) {
            return Result.fail("找到多个用户");
        }

        SysUser sysUser = sysUsers.get(0);
        if (!passwordEncoder.matches(password, sysUser.getPassword())) {
            return Result.fail("密码错误");
        }
        if (sysUser.getStatus() == 1) {
            return Result.fail("该账号已被冻结");
        }

        Integer userId = sysUser.getId();
        AdminJwt adminJwt = new AdminJwt();
        adminJwt.setUserId(userId);
        adminJwt.setUsername(username);
        adminJwt.setNickname(sysUser.getNickname());
        adminJwt.setDeptCode(sysUser.getDeptCode());
        adminJwt.setClientId(ClientEnum.ADMIN.getValue() + "");
        if (!username.equals("admin")) {
            //如果不是超级管理员 需要获取当前用户角色信息
            List<Integer> roleIds = sysUserRoleMapper.selectByUserId(userId);
            adminJwt.setRoleIds(roleIds);
        }
        String token = JwtTokenUtil.createAdminToken(adminJwt);
        return Result.ok(token);
    }

    @Override
    public Result<Object> imgCode() {
        // 获取运算的结果
        Captcha captcha = loginProperties.getCaptcha();
        String uuid = IdUtil.uuid();
        String imgCodeKey = RedisKeys.getImgCodeKey(uuid);
        //当验证码类型为 arithmetic时且长度 >= 2 时，captcha.text()的结果有几率为浮点型
        String captchaValue = captcha.text();
        if (captcha.getCharType() - 1 == CodeTypeEnum.arithmetic.ordinal() && captchaValue.contains(".")) {
            captchaValue = captchaValue.split("\\.")[0];
        }
        log.info("login_captchaValue=" + captchaValue);
        // 保存
        redisTemplate.opsForValue().set(imgCodeKey, captchaValue, loginProperties.getExpiration(), TimeUnit.MINUTES);
        // 验证码信息
        Map<String, String> imgResult = new HashMap<>(4);
        imgResult.put("img", captcha.toBase64());
        imgResult.put("uuid", uuid);
        return Result.ok(imgResult);
    }

//    @Override
//    public Result<LoginResp> pswLogin(LoginReq loginReq) throws Exception {
//
//        Result result = codeValidateUtil.validateImgCode(loginReq.getUuid(), loginReq.getCode());
//        if (result.isFail()) {
//            return result;
//        }
//
//        MerchantJwt merchantJwt = doLogin(loginReq, true);
//        LoginResp loginResp = getLoginResp(merchantJwt);
//
//        return Result.ok(loginResp);
//    }

//    @Override
//    public Result<LoginResp> smsLogin(MobileLoginReq loginReq) throws Exception {
//
//        Result result = codeValidateUtil.validateSmsCode(loginReq.getMobile(), SmsEnum.MERCHANT_LOGIN, loginReq.getCode());
//        if (result.isFail()) {
//            return result;
//        }
//
//        LoginReq req = new LoginReq(loginReq.getMobile());
//
//        MerchantJwt merchantJwt = doLogin(req, false);
//        LoginResp loginResp = getLoginResp(merchantJwt);
//
//        return Result.ok(loginResp);
//    }
//
//    @Override
//    public Result<LoginResp> wxLogin(WxLoginReq wxLoginReq) throws Exception {
//        String code = wxLoginReq.getCode();
//
//        WxMaUserService userService = merchantWxMaService.getUserService();
//        WxMaPhoneNumberInfo newPhoneNoInfo = userService.getNewPhoneNoInfo(code);
//        String mobile = newPhoneNoInfo.getPurePhoneNumber();
//
//        LoginReq req = new LoginReq(mobile);
//        MerchantJwt merchantJwt = doLogin(req, false);
//        LoginResp loginResp = getLoginResp(merchantJwt);
//
//        return Result.ok(loginResp);
//    }
//
//    @Override
//    public Result switchMerchant(Integer merchantId, MerchantJwt merchantJwt) {
//
//        //  切换至某个商家
//        if (merchantId != null) {
//
//            //  目标商家
//            Merchant targetMerchant = merchantMapper.selectById(merchantId);
//            if (ObjectUtil.isNull(targetMerchant)) {
//                throw new ServiceException("商家不存在");
//            }
//
//            //  校验是否可进入此商家
//            Member member = memberMapper.selectById(merchantJwt.getMemberId());
//            Integer typeId = member.getTypeId();
//            List<Integer> merchantIds = null;
//            if (member.getType() == MemberTypeEnum.MERCHANT.getValue()) {
//                merchantIds = merchantMapper.listIds(typeId, null);
//            } else if (member.getType() == MemberTypeEnum.MERCHANT_SUB.getValue()) {
//                merchantIds = merchantPersonMerchantMapper.merchantIds(typeId, null);
//            }
//            if (merchantIds == null) {
//                log.error("switchMerchant_fail, merchantIds is null, merchantId:{}, merchantJwt:{}, member:{}", merchantId, merchantJwt, member);
//                throw new ServiceException("当前账号无可切换商家");
//            }
//            if (!merchantIds.contains(merchantId)) {
//                throw new ServiceException("无权限进入此商家");
//            }
//
//            Integer status = targetMerchant.getStatus();
//            if (status == MerchantStatusEnum.WaitCheck.getValue() || status == MerchantStatusEnum.CheckFail.getValue()) {
//                throw new ServiceException("目标商家审核未通过，无法切换");
//            }
//        }
//
//        merchantJwt.setMerchantId(merchantId);
//        //  重新生成token
//        String token = JwtTokenUtil.createMchToken(merchantJwt);
//        return Result.ok(token);
//    }
//
//    @Override
//    public Result<List<MerchantSimpleVo>> merchants(List<Integer> merchantIds, Integer catId) {
//        List<Integer> notInStatuses = CollUtil.toList(MerchantStatusEnum.WaitCheck.getValue(), MerchantStatusEnum.CheckFail.getValue());
//        List<MerchantSimpleVo> list = merchantMapper.list(null, merchantIds, null, notInStatuses, catId);
//        return Result.ok(list);
//    }
//
//    /**
//     * 设置菜单
//     * @param merchantId
//     * @param roleIds
//     * @param info
//     * @return void
//     */
//    public void setMenuInfo(Integer merchantId, List<Integer> roleIds, MerchantAuthInfoVo info) {
//        List<SysMenu> sysMenus = sysMenuMapper.listMenuByRoleId(roleIds);
//        if (merchantId == null) {
//            sysMenus = sysMenus.stream().filter(menu -> !menu.getHideOnAllMerchant()).collect(Collectors.toList());
//        }
//
//        List<String> btnPermissions = sysMenus.stream()
//                .filter(menu -> menu.getType() == MenuTypeEnum.BUTTON.getValue())
//                .map(SysMenu::getPermission).collect(Collectors.toList());
//
//        //  构建菜单树
//        List<SysMenu> menus = sysMenus.stream().filter(menu -> (menu.getType() == MenuTypeEnum.FIRST.getValue() || menu.getType() == MenuTypeEnum.SUB.getValue())).collect(Collectors.toList());
//        List<MenuVo> menuVos = SysMenuConverter.INSTANCE.toMenuVoList(menus);
//        List<MenuVo> menuTree = sysMenuService.buildTree(menuVos);
//
//        info.setBtnPermissions(btnPermissions);
//        info.setMenus(menuTree);
//    }
//
//    /**
//     * 设置商家信息
//     * 商家：获取总店id
//     * 子账号：获取管理下的第一个商家
//     * @param member
//     * @return MerchantJwt
//     */
//    private MerchantJwt getMerchantJwt(Member member) {
//        MerchantJwt merchantJwt = new MerchantJwt();
//        Integer type = member.getType();
//        Integer typeId = member.getTypeId();
//        List<MerchantSimpleVo> merchants = null;
//        if (type == MemberTypeEnum.MERCHANT.getValue()) {
//            merchants = merchantMapper.list(null, null, typeId, null, null);
//        } else if (type == MemberTypeEnum.MERCHANT_SUB.getValue()) {
//            merchants = merchantPersonMerchantMapper.merchants(typeId, null, null);
//        }
//        long canEnterMerchantCount = merchants.stream().filter(merchant ->
//                merchant.getStatus() != MerchantStatusEnum.WaitCheck.getValue()
//                        && merchant.getStatus() != MerchantStatusEnum.CheckFail.getValue())
//                .count();
//        if (canEnterMerchantCount == 0) {
//            throw new ServiceException("账号下无可进入商家");
//        }
//        MerchantSimpleVo merchant = merchants.get(0);
//        if (merchants.size() == 1) {
//            merchantJwt.setMerchantId(merchant.getId());
//        }
//        merchantJwt.setHeadId(merchant.getPid() == 0 ? merchant.getId() : merchant.getPid());
//        List<Integer> merchantIds = merchants.stream().map(mer -> mer.getId()).collect(Collectors.toList());
//        merchantJwt.setPerMerIds(merchantIds);
//        merchantJwt.setMemberId(member.getId());
//        merchantJwt.setMobile(member.getMobile());
//        merchantJwt.setClientId(AppEnum.MERCHANT.name());
//        return merchantJwt;
//    }

    /**
     * 校验密码
     * @param encryptPsw
     * @param realPsw
     * @return void
     */
//    private void verifyPassword(String encryptPsw, String realPsw) throws Exception {
//        String inputPsw = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey, encryptPsw);
//        if (!passwordEncoder.matches(inputPsw, realPsw)) {
//            throw new ServiceException("密码错误");
//        }
//    }

    /**
     * 登陆逻辑
     * @param loginReq
     * @param isPswLogin
     * @return LoginResp
     */
//    private MerchantJwt doLogin(LoginReq loginReq, boolean isPswLogin) throws Exception {
//        String mobile = loginReq.getMobile();
//        String password = loginReq.getPassword();
//
//        //  校验
//        Member member = memberMapper.selectOne(Wrappers.lambdaQuery(Member.class).eq(Member::getMobile, mobile));
//        if (member == null) {
//            throw new ServiceException("帐号不存在");
//        }
//        Integer memberType = member.getType();
//        if (memberType != MemberTypeEnum.MERCHANT.getValue() && memberType != MemberTypeEnum.MERCHANT_SUB.getValue()) {
//            throw new ServiceException("无权限进入");
//        }
//        if (member.getStatus() == 1) {
//            throw new ServiceException("该账号已被冻结");
//        }
//        if (isPswLogin) {
//            verifyPassword(password, member.getPassword());
//        }
//
//        MerchantJwt merchantJwt = getMerchantJwt(member);
//        redisClient.setRemove(RedisKeys.CHANGE_TOKEN_ACCOUNT, mobile);
//        return merchantJwt;
//    }
//
//    /**
//     * 根据MerchantJwt生成LoginResp
//     * @param merchantJwt
//     * @return LoginResp
//     */
//    private LoginResp getLoginResp(MerchantJwt merchantJwt) {
//        String token = JwtTokenUtil.createMchToken(merchantJwt);
//        String refreshToken = JwtTokenUtil.createMchRefreshToken(merchantJwt);
//        return new LoginResp(token, refreshToken);
//    }

}
